package com.usian.admin.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.usian.admin.entity.AdChannel;
import com.usian.admin.service.IAdChannelService;
import com.usian.admin.service.IAdSensitiveService;
import com.usian.admin.service.WemediaNewsAutoService;
import com.usian.article.feign.ArticleFeign;
import com.usian.common.aliyun.GreenImageScan;
import com.usian.common.aliyun.GreenTextScan;
import com.usian.common.dtos.PageResult;
import com.usian.common.dtos.ResponseResult;
import com.usian.common.enums.AppHttpCodeEnum;
import com.usian.common.exception.LeadException;
import com.usian.common.util.JsonUtils;
import com.usian.common.util.SensitiveWordUtil;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsResultDTO;
import com.usian.model.media.dtos.WmUserDto;
import com.usian.wemedia.feign.WemediaFeign;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

import static com.usian.common.constants.message.Article2EsConstants.ARTICLE_2_ES_TOPIC;

@Service
@Slf4j

public class WemediaNewsAutoServiceImpl implements WemediaNewsAutoService {

    @Autowired
    private WemediaFeign wemediaFeign;

    @Autowired
    private IAdSensitiveService sensitiveService;

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private GreenImageScan greenImageScan;

    @Autowired
    private ArticleFeign articleFeign;

    @Autowired
    private IAdChannelService channelService;

    @Autowired
    private KafkaTemplate kafkaTemplate;


    @Override
    @GlobalTransactional
    public void auditWemediaNews(Integer wmNewId) {

//        远程调用-wemedia服务，根据wmNewsId查询自媒体文章信息
        ResponseResult<WmNewsResultDTO> result = wemediaFeign.findById(wmNewId);
        WmNewsResultDTO wmNewsResultDTO = result.getData();
        if (wmNewsResultDTO == null) {
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST, "自媒体文章数据数据不存在");
        }
        Integer status = wmNewsResultDTO.getStatus();
//        判断自媒体文章状态，进行操作
        if (status == 1) {
            //           如果是 1 -待审核
//               获取自媒体文章中所有的文字（文章得标题，和正文中得文字）和图片地址（封面图片和正文中得图片）
            Map<String, Object> contentMap = getTextAndImage(wmNewsResultDTO.getTitle(), wmNewsResultDTO.getContent(), wmNewsResultDTO.getImages());
//               检查敏感词
            List<String> sensitiveList = sensitiveService.findAllSensitive();
            Boolean b = handleSensitive(String.valueOf(contentMap.get("text")), sensitiveList, wmNewId);
            if (!b) {
                return;
            }
//               调用阿里云的接口审核文字
            Boolean b1 = handleTextScan(String.valueOf(contentMap.get("text")), wmNewId);
            if (!b1) {
                return;
            }
//               调用阿里云的接口审核图片
            Boolean b2 = handleImageScan((List<String>) contentMap.get("image"), wmNewId);
            if (!b2) {
                return;
            }
//               如果上面的检查都通过
//               远程调用-修改自媒体文章状态为8-审核通过
            updateWmNews(wmNewId, "通过", WmNewsResultDTO.Status.SUCCESS.getCode());
        }
        //判断发布时间是否存在，并且发布时间大于当前时间，什么都不需要做
        if (wmNewsResultDTO.getPublishTime() != null && wmNewsResultDTO.getPublishTime().getTime() > new Date().getTime()) {
            return;
        }

//           如果是 4 -人工审核通过，远程调用 -保存自媒体文章信息到文章库已发布
//           如果是 8 -审核通过待发布， 远程调用 -保存自媒体文章信息到文章库已发布
        if (status == WmNewsResultDTO.Status.SUCCESS.getCode() || status == WmNewsResultDTO.Status.ADMIN_SUCCESS.getCode()) {
            updateWmNews(wmNewId, "已发布", WmNewsResultDTO.Status.PUBLISHED.getCode());
        }
        //               远程调用-保存自媒体文章信息到文章库

        //组装频道名称参数

        AdChannel adChannel = channelService.getById(wmNewsResultDTO.getChannelId());
        if (adChannel != null) {
            wmNewsResultDTO.setChannelName(adChannel.getName());
        }
        ResponseResult<Long> responseResult = articleFeign.saveArticle(wmNewsResultDTO);
        Long articleId = responseResult.getData();
        //生产消息，同步文章数据到索引库
        kafkaTemplate.send(ARTICLE_2_ES_TOPIC,articleId);

    }

    @Override
    public void auditWmNewsTask() {
        //查询审核通过待发布得文章id集合
        List<Integer> list = wemediaFeign.findWmNewsIds();
        for (Integer wmNewsId : list) {
            auditWemediaNews(wmNewsId);
        }
    }

    /**
     * 分页查询 自媒体文章信息
     */
    @Override
    public PageResult<WmNewsResultDTO> findPage(NewsAuthDto dto) {
        PageResult<WmNewsResultDTO> result = wemediaFeign.findWmNewsByPage(dto);
        return result;
    }

    /**
     * 查询一条自媒体文章信息
     */
    @Override
    public ResponseResult<WmNewsResultDTO> findByWmNewsId(Integer id) {
        ResponseResult<WmNewsResultDTO> responseResult = wemediaFeign.findById(id);

        return responseResult;
    }


    private Boolean handleImageScan(List<String> imageList, Integer wmNewId) {
        try {
            Map<String, String> map = greenImageScan.imageScan(imageList);
            //判断文章文本是否能够通过阿里云文本反垃圾处理
            if (CollectionUtils.isEmpty(map)) {
                throw new LeadException(AppHttpCodeEnum.SERVER_ERROR, "调用阿里云图片反垃圾失败");
            }
            //获取阿里云返回得审核建议
            String suggestion = map.get("suggestion");
            if ("pass".equals(suggestion)) {
                //审核通过
                return true;
            }
            Integer status = "review".equals(suggestion) ? WmNewsResultDTO.Status.ADMIN_AUTH.getCode() : WmNewsResultDTO.Status.FAIL.getCode();
            //更新自媒体文章状态
            updateWmNews(wmNewId, map.get("label"), status);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR, "调用阿里云图片反垃圾失败");
        }

    }


    /**
     * 调用阿里云文本反垃圾审核文本内容
     *
     * @param text
     * @param wmNewId
     * @return
     */
    private Boolean handleTextScan(String text, Integer wmNewId) {
        try {
            Map<String, String> map = greenTextScan.greenTextScan(text);
            //判断文章文本是否能够通过阿里云文本反垃圾处理
            if (CollectionUtils.isEmpty(map)) {
                throw new LeadException(AppHttpCodeEnum.SERVER_ERROR, "调用阿里云文本反垃圾失败");
            }
            //获取阿里云返回得审核建议
            String suggestion = map.get("suggestion");
            if ("pass".equals(suggestion)) {
                //审核通过
                return true;
            }
            Integer status = "review".equals(suggestion) ? WmNewsResultDTO.Status.ADMIN_AUTH.getCode() : WmNewsResultDTO.Status.FAIL.getCode();
            //更新自媒体文章状态
            updateWmNews(wmNewId, map.get("reson"), status);
            return false;

        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR, "调用阿里云文本反垃圾失败");
        }

    }


    /*
     * 处理自媒体敏感词
     * */
    private Boolean handleSensitive(String text, List<String> sensitiveList, Integer wmNewId) {

        Map<String, Integer> map = SensitiveWordUtil.matchWords(sensitiveList, text);
        //判断map中是否有值
        if (!CollectionUtils.isEmpty(map)) {
            //自媒体文章中存在自定义得敏感词，审核未通过

            //更新自媒体状态
            updateWmNews(wmNewId, "存在敏感词", WmNewsResultDTO.Status.FAIL.getCode());
            return false;
        }
        return true;
    }

    /*
     * 更新自媒体文章得状态
     * 人工审核
     * */
    @Override
    public void updateWmNews(Integer wmNewId, String reason, int status) {
        WmNewsDto wmNewsDto = new WmNewsDto();
        wmNewsDto.setId(wmNewId);
        wmNewsDto.setReason(reason);
        wmNewsDto.setStatus(status);
        wemediaFeign.updateWmNews(wmNewsDto);
    }


    /**
     * 获取文章文本内容和图片（包含封面图片）
     *
     * @param title
     * @param content
     * @param images
     * @return
     */
    private Map<String, Object> getTextAndImage(String title, String content, String images) {

        HashMap<String, Object> map = new HashMap<>();
        //文本内容拼接
        StringBuilder stringBuilder = new StringBuilder();
        //拼接文章标题
        stringBuilder.append(title);
        //存储图片地址得集合
        List<String> imageUrlList = new ArrayList<>();


        //处理正文
        List<Map<String, String>> contentList = JsonUtils.nativeRead(content, new TypeReference<List<Map<String, String>>>() {
        });
        for (Map<String, String> contentMap : contentList) {
            if ("text".equals(contentMap.get("type"))) {
                stringBuilder.append(contentMap.get("value"));//文本
            }
            if ("image".equals(contentMap.get("type"))) {
                String imageUrl = contentMap.get("image");
                imageUrlList.add(imageUrl);
            }
        }

        //处理封面图片地址
        if (StringUtils.isNotBlank(images)) {
            String[] imageArr = images.split(",");
            imageUrlList.addAll(Arrays.asList(imageArr));
        }


        map.put("text", stringBuilder);
        map.put("image", imageUrlList);
        return map;
    }
}
